package cn.kgc.biz.service;

import cn.kgc.biz.vo.*;
import cn.kgc.dto.Dto;
import cn.kgc.mapper.*;
import cn.kgc.pojo.*;
import cn.kgc.util.DtoUtil;
import cn.kgc.util.FinalStaticUtil;
import cn.kgc.util.OrderNoUtil;
import cn.kgc.vo.HotelOrderWithLinkUserVo;
import cn.kgc.vo.PersonalOrderInfoVo;
import cn.kgc.vo.PersonalOrderRoomInfoVo;
import cn.kgc.vo.RoomPriceVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class HotelOrderServiceImpl implements HotelOrderService {
    @Resource
    private HotelOrderMapper hotelOrderMapper;
    @Resource
    private HotelTempStoreMapper hotelTempStoreMapper;
    @Resource
    private ProductStoreMapper productStoreMapper;
    @Resource
    private HotelRoomMapper hotelRoomMapper;
    @Resource
    private OrderLinkUserMapper  orderLinkUserMapper;
    @Resource
    private CallStoreMapper callStoreMapper;

    @Override
    public Dto getPersonalOrderList(PersonalOrderVo personalOrderVo) {
        HotelOrder hotelOrder=new HotelOrder();
        hotelOrder.setUserId(personalOrderVo.getUserId());
        if (personalOrderVo.getOrderStatus()!=null && personalOrderVo.getOrderStatus()!=-1){
            hotelOrder.setOrderStatus(personalOrderVo.getOrderStatus());
        }
        if (personalOrderVo.getOrderType()!=null&&personalOrderVo.getOrderType()!=-1){
            hotelOrder.setOrderType(personalOrderVo.getOrderType());
        }
        if (!StringUtil.isEmpty(personalOrderVo.getOrderNo())){
            hotelOrder.setOrderNo(personalOrderVo.getOrderNo());
        }
        if (!StringUtil.isEmpty(personalOrderVo.getLinkUserName())){
            hotelOrder.setLinkUserName(personalOrderVo.getLinkUserName());
        }
        if (personalOrderVo.getStartDate()!=null){
            hotelOrder.setCheckInDate(personalOrderVo.getStartDate());
        }
        if (personalOrderVo.getEndDate()!=null){
            hotelOrder.setCheckOutDate(personalOrderVo.getEndDate());
        }
        if(personalOrderVo.getPageNo()==null||personalOrderVo.getPageNo()==0){
            personalOrderVo.setPageNo(1);
        }
        PageHelper.startPage(personalOrderVo.getPageNo(),personalOrderVo.getPageSize());
        List<HotelOrder> hotelOrderList=hotelOrderMapper.queryOrdersByHotelOrder(hotelOrder);
        PageInfo<HotelOrder> pageInfo=new PageInfo<>(hotelOrderList);
        long total=pageInfo.getTotal();
        long pageNum=pageInfo.getPageNum();
        long pages=pageInfo.getPages();
        long pageSize=pageInfo.getPageSize();
        PageVo pageVo=new PageVo();
        pageVo.setBeginPos(0);
        pageVo.setCurPage(pageNum);
        pageVo.setPageSize(pageSize);
        pageVo.setTotal(total);
        pageVo.setPageCount(pages);
        pageVo.setRows(pageInfo.getList());
        return DtoUtil.getSuccesWithData(pageVo);
    }

    @Override
    public Dto getPreOrderInfo(PreOrderInfoVo preOrderInfoVo) {
        //计算temp_store表中是否有顾客入住当天的记录
        int count=hotelTempStoreMapper.countRecordDate(preOrderInfoVo.getRoomId(),preOrderInfoVo.getCheckInDate());
        long store;
        if (count>0){
            store=hotelTempStoreMapper.getMinStore(preOrderInfoVo.getRoomId(),preOrderInfoVo.getCheckInDate(),preOrderInfoVo.getCheckOutDate());
        }else {
            store=productStoreMapper.getMinStore(preOrderInfoVo.getRoomId());
        }
        int count1=0;
        Integer count2=hotelOrderMapper.countOfOrderByStatus(preOrderInfoVo.getCheckInDate(),preOrderInfoVo.getCheckOutDate(),preOrderInfoVo.getRoomId());
        if (!ObjectUtils.isEmpty(count2)){
             count1=count2;
        }
        long realStore=store-count1;
        CountRoomOrderVo countRoomOrderVo=new CountRoomOrderVo();
        countRoomOrderVo.setStore(realStore);
        countRoomOrderVo.setCheckInDate(preOrderInfoVo.getCheckInDate());
        countRoomOrderVo.setCheckOutDate(preOrderInfoVo.getCheckOutDate());
        countRoomOrderVo.setCount(preOrderInfoVo.getCount());
        countRoomOrderVo.setHotelId(preOrderInfoVo.getHotelId());
        countRoomOrderVo.setRoomId(preOrderInfoVo.getRoomId());
        RoomPriceVo roomPriceVo=hotelRoomMapper.getRoomPrice(preOrderInfoVo.getRoomId());
        countRoomOrderVo.setHotelName(roomPriceVo.getHotelName());
        //判定是否当天订，当天退
        int bookingDays=1;
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        if (!sdf.format(preOrderInfoVo.getCheckInDate()).equals(sdf.format(preOrderInfoVo.getCheckOutDate()))){
            long time=preOrderInfoVo.getCheckOutDate().getTime()-preOrderInfoVo.getCheckInDate().getTime();
            bookingDays=(int)time/(1000*60*60*24);
        }
        countRoomOrderVo.setPrice(preOrderInfoVo.getCount()*roomPriceVo.getRoomPrice()*bookingDays);
        return DtoUtil.getSuccesWithData(countRoomOrderVo);
    }

    @Override
    public Dto getPersonalOrderInfo(String orderId) {
        if (StringUtil.isEmpty(orderId)){
            return DtoUtil.getFalseDto("数据异常","500001");
        }
        PersonalOrderInfoVo personalOrderInfoVo =hotelOrderMapper.getPersonalOrderInfo(Long.parseLong(orderId));
        if (personalOrderInfoVo.getOrderStatus()==1){
            personalOrderInfoVo.setOrderProcess(FinalStaticUtil.ORDERPROCESS_STATUS_1);
            personalOrderInfoVo.setProcessNode(3);
        }else {
            personalOrderInfoVo.setOrderProcess(FinalStaticUtil.ORDERPROCESS_STATUS_2);
            if (personalOrderInfoVo.getOrderStatus()==0){
                personalOrderInfoVo.setProcessNode(2);
            }else if (personalOrderInfoVo.getOrderStatus()==2){
                personalOrderInfoVo.setProcessNode(3);
            }else if (personalOrderInfoVo.getOrderStatus()==3){
                personalOrderInfoVo.setProcessNode(4);
            }else if (personalOrderInfoVo.getOrderStatus()==4){
                personalOrderInfoVo.setProcessNode(5);
            }else{
                personalOrderInfoVo.setProcessNode(6);
            }
        }
        return DtoUtil.getSuccesWithData(personalOrderInfoVo);
    }

    @Override
    public Dto getPersonalOrderRoomInfo(String orderId) {
        if (StringUtil.isEmpty(orderId)){
            return DtoUtil.getFalseDto("数据异常","500001");
        }
        PersonalOrderRoomInfoVo personalOrderRoomInfoVo= hotelOrderMapper.getPersonalOrderRoomInfo(Long.parseLong(orderId));
        return DtoUtil.getSuccesWithData(personalOrderRoomInfoVo);
    }

    @Override
    public Dto addHotelOrder(User user, AddHotelOrderVo addHotelOrderVo) {
        //已经支付过后的房间数
        callStoreMapper.callPreFlushStore(addHotelOrderVo.getCheckInDate(),addHotelOrderVo.getCheckOutDate(),addHotelOrderVo.getRoomId(),addHotelOrderVo.getHotelId());
        //计算temp_store表中是否有顾客入住当天的记录
        long count1 =hotelTempStoreMapper.getMinStore(addHotelOrderVo.getRoomId(),addHotelOrderVo.getCheckInDate(),addHotelOrderVo.getCheckOutDate());
        Integer count2=hotelOrderMapper.countOfOrderByStatus(addHotelOrderVo.getCheckInDate(),addHotelOrderVo.getCheckOutDate(),addHotelOrderVo.getRoomId());
        if (ObjectUtils.isEmpty(count2)){
            count2=0;
        }
        long store=count1-count2;
        //如果库存小于顾客所定的房间数，则提示前端订单生成失败
        if (store<addHotelOrderVo.getCount()){
            return DtoUtil.getFalseDto("订单生成失败","600000");
        }
        //如果满足条件执行下面步骤
        //更新订单表
        HotelOrder hotelOrder=new HotelOrder();
        Date date=new Date();
        hotelOrder.setCheckInDate(addHotelOrderVo.getCheckInDate());
        hotelOrder.setCheckOutDate(addHotelOrderVo.getCheckOutDate());
        List<UserLinkUser> linkUser=addHotelOrderVo.getLinkUser();
        StringBuilder linkUserNames=new StringBuilder();
        for (UserLinkUser lu:linkUser){
            linkUserNames.append(lu.getLinkUserName()+",");
        }
        String name=linkUserNames.substring(0,linkUserNames.lastIndexOf(","));
        hotelOrder.setLinkUserName(name);
        hotelOrder.setUserId(user.getId());
        hotelOrder.setCount(addHotelOrderVo.getCount());
        hotelOrder.setHotelId(addHotelOrderVo.getHotelId());
        hotelOrder.setHotelName(addHotelOrderVo.getHotelName());
        hotelOrder.setInvoiceHead(addHotelOrderVo.getInvoiceHead());
        hotelOrder.setInvoiceType(addHotelOrderVo.getInvoiceType());
        hotelOrder.setIsNeedInvoice(addHotelOrderVo.getIsNeedInvoice());
        hotelOrder.setNoticeEmail(addHotelOrderVo.getNoticeEmail());
        hotelOrder.setNoticePhone(addHotelOrderVo.getNoticePhone());
        hotelOrder.setOrderType(addHotelOrderVo.getOrderType());
        hotelOrder.setRoomId(addHotelOrderVo.getRoomId());
        hotelOrder.setSpecialRequirement(addHotelOrderVo.getSpecialRequirement());
        HotelRoom hotelRoom=hotelRoomMapper.selectByPrimaryKey(addHotelOrderVo.getRoomId());
        hotelOrder.setOrderStatus(0);
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        //判定是否当天订，当天退
        int bookingDays=1;
        if (!sdf.format(addHotelOrderVo.getCheckInDate()).equals(sdf.format(addHotelOrderVo.getCheckOutDate()))){
            long time=addHotelOrderVo.getCheckOutDate().getTime()-addHotelOrderVo.getCheckInDate().getTime();
            bookingDays=(int)time/(1000*60*60*24);
        }
        hotelOrder.setBookingDays(bookingDays);
        hotelOrder.setPayAmount(hotelRoom.getRoomPrice()*addHotelOrderVo.getCount()*bookingDays);
        hotelOrder.setBookType(addHotelOrderVo.getBookType());
        //如果是第一次增加订单则执行以下步骤
        if (addHotelOrderVo.getId()==null || addHotelOrderVo.getId()==0){
            hotelOrder.setCreationDate(date);
            hotelOrder.setCreatedBy(user.getId());
            hotelOrder.setOrderNo(OrderNoUtil.getOrderNo(date));
            int result1=hotelOrderMapper.insert(hotelOrder);
            if (result1==0){
                return DtoUtil.getFalseDto("订单生成失败","600001");
            }
            HotelOrder hotelOrder1=hotelOrderMapper.selectOne(hotelOrder);
            Long orderId =hotelOrder1.getId();
            OrderLinkUser orderLinkUser=new OrderLinkUser();
            for (UserLinkUser lu:linkUser){
                //如果插入成功则插入order_link_user
                orderLinkUser.setOrderId(orderId);
                orderLinkUser.setLinkUserId(lu.getId());
                orderLinkUser.setLinkUserName(lu.getLinkUserName());
                orderLinkUser.setCreationDate(date);
                orderLinkUser.setCreatedBy(user.getId());
                int result2=orderLinkUserMapper.insert(orderLinkUser);
                if (result2==0){
                    return DtoUtil.getFalseDto("数据异常","600002");
                }
            }
            return DtoUtil.getSuccesWithData(hotelOrder1);
        }
        //如果是修改订单则执行以下2步骤
        hotelOrder.setId(addHotelOrderVo.getId());
        hotelOrder.setModifyDate(date);
        hotelOrder.setCreationDate(date);
        hotelOrder.setCreatedBy(user.getId());
        hotelOrder.setOrderNo(addHotelOrderVo.getOrderNo());
        hotelOrder.setModifiedBy(user.getId());
        int result=hotelOrderMapper.updateByPrimaryKey(hotelOrder);
        if (result==0){
            return DtoUtil.getFalseDto("订单生成失败","600001");
        }
        HotelOrder hotelOrder1=hotelOrderMapper.selectOne(hotelOrder);
        Long orderId =hotelOrder1.getId();
        OrderLinkUser orderLinkUser=new OrderLinkUser();
        //先删除order_link_user中的关联联系人
        orderLinkUserMapper.deleteByOrderId(orderId);
        for (UserLinkUser lu:linkUser){
            //如果插入成功则插入order_link_user
            orderLinkUser.setOrderId(orderId);
            orderLinkUser.setLinkUserId(lu.getId());
            orderLinkUser.setLinkUserName(lu.getLinkUserName());
            orderLinkUser.setCreationDate(date);
            orderLinkUser.setCreatedBy(user.getId());
            int result2=orderLinkUserMapper.insert(orderLinkUser);
            if (result2==0){
                return DtoUtil.getFalseDto("数据异常","600002");
            }
        }
        return DtoUtil.getSuccesWithData(hotelOrder1);
    }

    @Override
    public Dto queryOrderById(Long orderId) {
        if (orderId==0){
            return DtoUtil.getFalseDto("数据异常","600002");
        }
        HotelOrderWithLinkUserVo hotelOrderWithLinkUserVo=hotelOrderMapper.getHotelOrderWithLinkUser(orderId);
        return DtoUtil.getSuccesWithData(hotelOrderWithLinkUserVo);
    }
}
